package com.autoagent.ai_live_master.webSocket.service;

import com.autoagent.ai_live_master.webSocket.handler.SocketIOHandler;
import com.autoagent.ai_live_master.webSocket.model.WordCloudEntry;
import com.autoagent.ai_live_master.webSocket.model.WordStats;
import com.autoagent.ai_live_master.webSocket.vo.BulletScreenWordCloudMessage;
import com.autoagent.ai_live_master.webSocket.vo.FormulaicScriptMessage;
import com.autoagent.ai_live_master.webSocket.vo.LiveMasterMessage;
import com.autoagent.ai_live_master.webSocket.vo.RecommendedScriptMessage;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.huaban.analysis.jieba.JiebaSegmenter;
import com.huaban.analysis.jieba.SegToken;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Service;
// 新增导入
import com.fasterxml.jackson.core.type.TypeReference;
import org.springframework.core.io.ClassPathResource;
import lombok.extern.slf4j.Slf4j;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ThreadLocalRandom;
import java.util.stream.Collectors;

@Slf4j
@Service
public class WordCloudService {

    private final JiebaSegmenter segmenter = new JiebaSegmenter();

    // 词频统计表（线程安全）
    // 房间ID -> (词语 -> (词频，更新时间))
    // 房间ID -> 词频映射
    private final Map<String, Map<String, WordStats>> roomWordFreqMap = new ConcurrentHashMap<>();

    // 停用词（可自定义）
    private final Set<String> stopWords = Set.of("的", "了", "是", "在", "我", "你", "我们", "他们", "就");

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper()
            .configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    // 词云淘汰阈值（毫秒）
    private static final long WORD_EXPIRATION_TIME_MS = 5 * 60 * 1000; // 5分钟

    // 每次推送最多的词数量
    private static final int MAX_WORD_COUNT = 50;

    @Autowired
    private SocketIOHandler socketIOHandler;

    @Autowired
    private FormulaicScriptService formulaicScriptService;

    // 新增：懒加载的 mock 文案
    private volatile String formulaicScriptText; // 定式话术（整段文本）
    private volatile List<String> recommendedScriptList; // 推荐话术（JSON 数组）

    // 每条弹幕进来后调用此方法进行分词统计
    public void addMessage(String roomId, String content) {
        String cleanContent = stripHtmlTags(content);
        List<SegToken> tokens = segmenter.process(cleanContent, JiebaSegmenter.SegMode.SEARCH);
        Map<String, WordStats> wordFreqMap = roomWordFreqMap.computeIfAbsent(roomId, k -> new ConcurrentHashMap<>());

        for (SegToken token : tokens) {
            String word = token.word;
            if (!stopWords.contains(word) && word.length() > 1) {
                wordFreqMap.compute(word, (k, v) -> {
                    if (v == null) return new WordStats(1, System.currentTimeMillis());
                    v.increment();
                    return v;
                });
            }
        }
    }

    // 定期（比如每 30 秒）获取词云数据并清空旧数据
    @Scheduled(fixedRate = 10000)
    public void generateAndPushWordCloud() throws JsonProcessingException {

        // 确保 mock 文案已加载
        ensureMockScriptsLoaded();

        for (String roomId : roomWordFreqMap.keySet()) {
            Map<String, WordStats> wordFreqMap = roomWordFreqMap.get(roomId);
            cleanupOldWords(wordFreqMap);

            List<WordCloudEntry> wordCloudList = wordFreqMap.entrySet().stream()
                    .sorted((a, b) -> b.getValue().getCount() - a.getValue().getCount())
                    .limit(MAX_WORD_COUNT)
                    .map(e -> new WordCloudEntry(e.getKey(), e.getValue().getCount()))
                    .collect(Collectors.toList());

            // 构建词云消息体
            BulletScreenWordCloudMessage wordCloudMessage = new BulletScreenWordCloudMessage(wordCloudList);
            String wordCloudJson = OBJECT_MAPPER.writeValueAsString(wordCloudMessage);
            
            //构建推荐话术（随机轮播）
            String recContent = "";
            if (recommendedScriptList != null && !recommendedScriptList.isEmpty()) {
                int idx = ThreadLocalRandom.current().nextInt(recommendedScriptList.size());
                recContent = recommendedScriptList.get(idx);
            }
            RecommendedScriptMessage recommended = new RecommendedScriptMessage(
                    recContent,
                    "产品推荐,优惠,性价比",
                    true,
                    "rec-" + UUID.randomUUID()
            );
            
            String recommendedJson= OBJECT_MAPPER.writeValueAsString(recommended);
            
            // 广播消息 - 只发送词云和推荐话术，定式话术单独发送
            socketIOHandler.broadcast(roomId,wordCloudJson);
            socketIOHandler.broadcast(roomId,recommendedJson);
        }
    }

    // 确保文案只加载一次（懒加载 + 双重校验）
    private void ensureMockScriptsLoaded() {
        if (formulaicScriptText == null || recommendedScriptList == null) {
            synchronized (this) {
                if (formulaicScriptText == null) {
                    formulaicScriptText = loadFormulaicScript();
                }
                if (recommendedScriptList == null) {
                    recommendedScriptList = loadRecommendedScripts();
                }
            }
        }
    }

    private List<String> loadRecommendedScripts() {
        try {
            ClassPathResource resource = new ClassPathResource("推荐话术示例文案.txt");
            try (InputStream is = resource.getInputStream()) {
                List<String> list = OBJECT_MAPPER.readValue(is, new TypeReference<List<String>>(){});
                return list != null ? list : new ArrayList<>();
            }
        } catch (IOException e) {
            // 读取失败时返回空列表，避免影响主流程
            return new ArrayList<>();
        }
    }

    private String loadFormulaicScript() {
        try {
            ClassPathResource resource = new ClassPathResource("定式话术示例文案.txt");
            try (InputStream is = resource.getInputStream()) {
                return new String(is.readAllBytes(), StandardCharsets.UTF_8);
            }
        } catch (IOException e) {
            return ""; // 读取失败时返回空字符串
        }
    }

    /**
     * 清理词频表中过期的词
     */
    private void cleanupOldWords(Map<String, WordStats> wordFreqMap) {
        long now = System.currentTimeMillis();
        wordFreqMap.entrySet().removeIf(e -> (now - e.getValue().getLastUpdateTime()) > WORD_EXPIRATION_TIME_MS);
    }

    private String stripHtmlTags(String html) {
        return html.replaceAll("<[^>]*>", ""); // 清除所有 HTML 标签
    }

    public void resetWordFreqData() {
        roomWordFreqMap.clear();
    }

    /**
     * 发送定式话术（只在启动时调用一次）
     */
    public void sendFormulaicScript(String roomId) throws JsonProcessingException {
        // 确保 mock 文案已加载
        ensureMockScriptsLoaded();
        
        // 构建定式话术 - 使用真实数据
        String realFormulaicScript = formulaicScriptService.getFormulaicScriptByRoomId(roomId);
        FormulaicScriptMessage formulaicScriptData = new FormulaicScriptMessage(
                realFormulaicScript != null && !realFormulaicScript.isEmpty() ? realFormulaicScript : 
                (formulaicScriptText != null ? formulaicScriptText : ""),
                "fml-" + UUID.randomUUID()
        );
        
        // 直接发送FormulaicScriptMessage格式，不包装成LiveMasterMessage
        String formulaicJson = OBJECT_MAPPER.writeValueAsString(formulaicScriptData);
        socketIOHandler.broadcast(roomId, formulaicJson);
        
        log.info("已发送定式话术到房间: {}", roomId);
    }

}

